using System.Runtime.Loader;
using LearnRouting;
using LearnRouting.Models;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRouting(options =>
{
    options.ConstraintMap.Add("pos",typeof(PositionConstraint));
});

var app = builder.Build();


app.UseRouting();



app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/", async (HttpContext context) =>
    {
        await context.Response.WriteAsync("Welcome to the home page");
    });
    
    // endpoints.MapGet("/employees", async (HttpContext context) =>
    // {
    //     var employees = EmployeeRepository.GetEmployees();
    //
    //     context.Response.ContentType = "text/html";
    //     await context.Response.WriteAsync("<h2>Employees</h2>");
    //     await context.Response.WriteAsync("<ul>");
    //     foreach (var value in employees)
    //     {
    //         await context.Response.WriteAsync($"<li><b>{value.Name}</b>:{value.Position}</li>");
    //     }
    //     
    //     await context.Response.WriteAsync("</ul>");
    //
    // });
    

    // bind to query value
    // endpoints.MapGet("/employees", ([FromQuery]int? identityNumber) =>
    // {
    //     if (identityNumber.HasValue)
    //     {
    //         var employee = EmployeeRepository.GetEmployeesById(identityNumber.Value);
    //         return employee;
    //     }
    //
    //     return null;
    // });
    
    
    // bind to http headers
    // endpoints.MapGet("/employees", ([FromHeader(Name = "identity")]int id) =>
    // {
    //     var employee = EmployeeRepository.GetEmployeesById(id);
    //     return employee;
    // });
    
  
    // use asparameters to group parameters
    endpoints.MapGet("/employees/{id:int}", ([AsParameters]GetEmployeeParameter param) =>
    {
        var employee = EmployeeRepository.GetEmployeesById(param.Id);

        employee.Name = param.Name;
        employee.Position = param.Position;
        
        return employee;
    });
    
    
    // bind arrays to query strings or headers
    endpoints.MapGet("/employees", (int[] ids) =>
    {
        var employees = EmployeeRepository.GetEmployees();
        var emps = employees.Where(x => ids.Contains(x.Id)).ToList();

        return emps;
    });

    // bind to http body
    endpoints.MapPost("/employees", (Employee employee) =>
    {
        if (employee is null || employee.Id <= 0)
        {
            return "Employee is not provided or is not valid";
        }
        
        EmployeeRepository.AddEmployee(employee);
        return "Employee addad successfully";
    });
    
    // custom binding with buildasync method
    endpoints.MapGet("/people", (Person? p) =>
    {
        return $"Id is {p?.Id};Name is {p?.Name}";
    });
    
    endpoints.MapPost("/employees", async (HttpContext context) =>
    {
        await context.Response.WriteAsync("Create an employees");
    });
    
    endpoints.MapPut("/employees", async (HttpContext context) =>
    {
        await context.Response.WriteAsync("Update an employees");
    });

    endpoints.MapDelete("/employees/{id}", async (HttpContext context) =>
    {
        await context.Response.WriteAsync($"Delete an employees:{context.Request.RouteValues["id"]}");
    });
    
    // route parameters with default values
    endpoints.MapGet("/{category=computer}/{size=medium}", async (HttpContext context) =>
    {
        await context.Response.WriteAsync($"Get category in category{context.Request.RouteValues["category"]}:" +
                                          $" in size:{context.Request.RouteValues["size"]}");
    });
    
    // optional parameters,id is optional parameters
    endpoints.MapDelete("/category/{id?}", async (HttpContext context) =>
    {
        await context.Response.WriteAsync($"Delete an employees:{context.Request.RouteValues["id"]}");
    });

    // parameters constraints
    endpoints.MapGet("/employees/{id:int}", async (HttpContext context) =>
    {
        await context.Response.WriteAsync($"Get employees:{context.Request.RouteValues["id"]}");
    });
    
    endpoints.MapGet("/employees/names/{name}", async (HttpContext context) =>
    {
        await context.Response.WriteAsync($"Get employees:{context.Request.RouteValues["name"]}");
    });
    
    
    endpoints.MapGet("/employees/positions/{position:pos}", async (HttpContext context) =>
    {
        await context.Response.WriteAsync($"Get employees under position :{context.Request.RouteValues["position"]}");
    });
    
});


app.Run();



struct GetEmployeeParameter
{
    [FromRoute]
    public int Id { get; set; }
    [FromQuery]
    public string Name { get; set; }
    [FromHeader]
    public string Position { get; set; }
}

